package com.mazaiting.net

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Environment
import com.facebook.react.bridge.*
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.modules.core.DeviceEventManagerModule
import com.tencent.cos.xml.CosXmlService
import com.tencent.cos.xml.CosXmlServiceConfig
import com.tencent.cos.xml.exception.CosXmlClientException
import com.tencent.cos.xml.exception.CosXmlServiceException
import com.tencent.cos.xml.listener.CosXmlResultListener
import com.tencent.cos.xml.model.CosXmlRequest
import com.tencent.cos.xml.model.CosXmlResult
import com.tencent.cos.xml.model.`object`.GetObjectRequest
import com.tencent.qcloud.core.auth.ShortTimeCredentialProvider

/**
 * 下载APK模块
 * Created by mazaiting on 2018/7/13.
 */

@ReactModule(name = "Download")
class DownloadModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
  /**
   * 对象存储的服务 APPID
   */
  private val appid = "1256286377"
  /**
   * 存储桶所在的区域
   */
  private val regison = "ap-chengdu"
  /**
   * 密钥ID
   */
  private val secretId = "AKIDvhFdniys77sSntpZ3LOFsGPJyRfeZvBg"
  /** 密钥KEY */
  private val secretKey = "jGYbP0LTLxUs0tWsy60fAQTHp9D2cy5x"
  /** SecretKey有效时间，单位秒 */
  private val keyDuration = 600L
  /** cos服务 */
  private var cosXmlService: CosXmlService? = null
  /** 网络请求 */
  private var getObjectRequest: GetObjectRequest? = null
  
  override fun getName(): String {
    return "Download"
  }
  
  /**
   * 初始化CosXmlService
   */
  private fun init() {
    // 创建CosXmlServiceConfig对象，根据需要修改默认的配置参数
    val serviceConfig = CosXmlServiceConfig
            .Builder()
            .setAppidAndRegion(appid, regison)
            .setDebuggable(true)
            .builder()
    
    // 创建获取签名类
    val localCredentialProvider = ShortTimeCredentialProvider(secretId, secretKey, keyDuration)
    // 创建CosXmlService
    cosXmlService = CosXmlService(reactContext, serviceConfig, localCredentialProvider)
  }
  
  /**
   * 下载文件
   * @param name 文件名
   */
  @ReactMethod
  fun downloadApk(name: String, successCallback: Callback, errorCallback: Callback) {
    // 初始化相应的数据
    init()
    // 对象存储桶名称
    val bucket = "test-$appid"
    // 文件路径
//    val cosPath = "huihe.apk"
    // 签名的有效期，单位为秒
    val signDuration = 600L
    // 待上传文件路径
    val srcPath = "${Environment.getExternalStorageDirectory()}/huihe/"
    // 获取请求
    getObjectRequest = GetObjectRequest(bucket, name, srcPath)
    // 设置签名
    getObjectRequest!!.setSign(signDuration, null, null)
    // 进度临时值
    var tmp = 0
    // 设置进度显示
    getObjectRequest!!.setProgressListener { progress, max ->
      // 获取返回结果
      val result = (progress * 100.0 / max)
//      Log.e(TAG, "progress = $result %")
      // 判断进度是否与上一次更新相同，如果相同则不更新，减少UI更新次数
      if (result.toInt() != tmp) {
        // 将进度值赋值给进度临时值
        tmp = result.toInt()
        // 为RN发送进度
        val params = Arguments.createMap()
//        Log.e(TAG, "progress = $tmp")
        params.putInt("progress", tmp)
        // 发送
        sendProgressEvent(reactContext, "downloadApk", params)
      }
    }
    
    // 使用异步回调请求
    cosXmlService!!.getObjectAsync(getObjectRequest, object : CosXmlResultListener {
      override fun onSuccess(cosXmlRequest: CosXmlRequest?, cosXmlResult: CosXmlResult?) {
//        Log.e(TAG, "success")
        successCallback.invoke("success")
        startInstallActivity(reactContext, "$srcPath$name")
      }
      
      override fun onFail(cosXmlRequest: CosXmlRequest?, clientException: CosXmlClientException?, serviceException: CosXmlServiceException?) {
        val errorMsg = clientException?.toString() ?: serviceException.toString()
        errorCallback.invoke(errorMsg)
//        Log.e(TAG, errorMsg)
      }
    })
    
  }
  
  /**
   * 取消下载
   */
  @ReactMethod
  fun cancel() {
    // 取消
    cosXmlService!!.cancel(getObjectRequest)
    cosXmlService!!.release()
    cosXmlService = null
  }
  
  /**
   * 发送事件
   */
  private fun sendProgressEvent(reactContext: ReactApplicationContext, eventName: String, params: WritableMap?) {
    reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
            .emit(eventName, params)
  }
  
  /**
   * 安装应用
   */
  private fun startInstallActivity(context: Context, path: String) {
    val install = Intent(Intent.ACTION_VIEW)
    install.setDataAndType(Uri.parse("file://" + path), "application/vnd.android.package-archive")
    install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    context.startActivity(install)
  }
  
}
